/*
 * @Author: chengjiang
 * @Date: 2024-05-20 11:41:39
 * @Description: 实时黄金数据。
 */
// 每一个存储的模块，命名规则use开头，store结尾
import { defineStore } from 'pinia'
import type {GoldInfo, Result } from '@/api/gold'
import { ListGoldSetting, GetOpenClose } from '@/api/gold'
import { ref } from 'vue'
import axios from 'axios'
export const useGoldInfoStore = defineStore({
  id: 'goldInfo', // 必须指明唯一的pinia仓库的id
  state: () => {
    return {
      name: '黄金',
      buy : 0,
      sell : 0,
      goldInfoList: [] as GoldInfo[],
      ws: null as WebSocket | null,
      isOpen: ref(''),
      pubtime: ref(''),
      goldMap: new Map<string, GoldInfo>(),
      isOpenByBack: ref(''),
      buyChange: 0,
      sellChange: 0,
    }
  },
  getters: {
    doubleCount: (state) => state
  },
  actions: {
    change(buy : number, sell : number) {
      this.buy = buy
      this.sell = sell
    },
    // 链接socket
    connectSocket(){
      this.ws = new WebSocket('wss://djkx.djkx9999.com/web/v1/ws')
    },
    disconnect() {
      if (this.ws) {
        this.ws.close()
        this.ws = null
      }
    },
    async freshListener() {
      this.buyChange = 0
      this.sellChange = 0
      // 拦截socket
      if (this.ws) {
        console.log('监听socket')
        try {
          await this.getBackGoldChange().then((ret) => {
            if (ret.Buy) {
              this.buyChange = ret.Buy
              this.sellChange = ret.Sell
            }
          })
        } catch (error) {
          console.error('getBackGoldChange 请求接口失败:', error);
        }
        this.ws.onmessage = this.handlerSocketData
      }
    },
    // this.goldInfoList转为 goldMap<name, goldInfo>
    setGoldInfoMap() {
      this.httpData()
      this.goldMap = new Map<string, GoldInfo>()
      // this.goldInfoList转为 goldMap<name, goldInfo>
      this.goldInfoList.forEach((item : GoldInfo) => {
        this.goldMap.set(item.name as string, item)
      })
    },
    httpData() { 
      // 直接访问这个接口：
      // https://djkx.djkx9999.com/web/v1/prices/list
      // console.log('开始请求接口')
      axios.get('https://djkx.djkx9999.com/web/v1/prices/list?t=' + Date.now())
      .then((response) => {
        console.log('接口返回数据:', response.data[0])
        this.handlerSocketData(response.data[0])
      })
      .catch((error) => {
        console.error('请求失败:', error)
      })
    },
    // 获取tabledata
    handlerSocketData(event: any) {
      this.goldInfoList.length = 0
      // 遍历map：
      const sortName: string[] = [
        '黄金',
        '白银',
        '黄金9999',
        '黄金(T+D)',
        '白银(T+D)',
        '铂金9995',
        // '美黄金',
        // '美白银',
        // '美铂金',
        // '美钯金',
        '国际金',
        '国际银',
        '国际铂',
        '国际钯',
        '伦敦金',
        '伦敦银',
        '伦敦铂',
        '伦敦钯',
        '美元'
      ]
      // 国际金算法添加:
      const nationalAlgorithmFactor : number = 31.1034768
      const name2NationalNameMap = new Map<string, string>()
      name2NationalNameMap.set('伦敦金', '国际金')
      name2NationalNameMap.set('伦敦银', '国际银')
      name2NationalNameMap.set('伦敦铂', '国际铂')
      name2NationalNameMap.set('伦敦钯', '国际钯')
      // 
      const sortEnglishNameMap = new Map<string, string>()
      sortEnglishNameMap.set('GOLD', '黄金')
      sortEnglishNameMap.set('SILVER', '白银')
      sortEnglishNameMap.set('AU9999', '黄金9999')
      sortEnglishNameMap.set('AUTD', '黄金(T+D)')
      sortEnglishNameMap.set('AGTD', '白银(T+D)')
      sortEnglishNameMap.set('TMAP9995', '铂金9995')
      // sortEnglishNameMap.set('美黄金', 'SILVER')
      // sortEnglishNameMap.set('美白银', 'SILVER')
      // sortEnglishNameMap.set('美铂金', 'SILVER')
      // sortEnglishNameMap.set('美钯金', 'SILVER')
      sortEnglishNameMap.set('XAU', '伦敦金')
      sortEnglishNameMap.set('XAG', '伦敦银')
      sortEnglishNameMap.set('XAP', '伦敦铂')
      sortEnglishNameMap.set('XPD', '伦敦钯')
      sortEnglishNameMap.set('USDCNH', '美元')
      // 获取数据
      // const ws_data = JSON.parse(event.data)
      // console.log('通过拦截得到的数据：', ws_data)
      // test = {
      //   date: '',
      //   priceData: {}, // items
      //   status: '开盘',
      // }
      // 封装:
      const res: Result = event
      const filterMap: Map<string, GoldInfo> = new Map<string, GoldInfo>()
      for (const [key, value] of Object.entries(res.items)) {
        if (sortEnglishNameMap.get(key) === undefined) {
          continue
        }
        const t: GoldInfo = value
        t.name = sortEnglishNameMap.get(key) as string
        filterMap.set(key, t)
      }
      res.items = filterMap
      // 国际金算法添加:
      const America:GoldInfo = res.items.get('USDCNH') as GoldInfo
      for (const [key, value] of res.items) {
        if (name2NationalNameMap.has(value.name as string)) {
          const tmpgold: GoldInfo = {
            name: name2NationalNameMap.get(value.name as string) as string,
            Buy: parseFloat(value.Buy+"") / nationalAlgorithmFactor * America.Buy,
            Sell: parseFloat(value.Sell+'') / nationalAlgorithmFactor * America.Sell,
            H: parseFloat(value.H+'') / nationalAlgorithmFactor * America.Sell,
            L: parseFloat(value.L+'') / nationalAlgorithmFactor * America.Sell,
            MaxMni: {
              H: parseFloat(value.H+'') / nationalAlgorithmFactor * America.Sell,
              L: parseFloat(value.L+'') / nationalAlgorithmFactor * America.Sell
            },
            C: name2NationalNameMap.get(value.name as string) as string
          }
          filterMap.set(tmpgold.name as string, tmpgold)
        }
      }
      // console.log('清理后的数据：', res.items)
      // 黄金数据需要根据时间段控制选择不同的数据加减，其他时间段保持更改数据不变，
      // 要求如下，9:00 - 15:30  周一到周五    黄金价格在黄金9999基础上加减五毛
      // 晚上：20:00 - 2:00   周一到周五    黄金价格在黄金T+D基础上 加减五毛
      const currentTime = new Date()
      const dayOfWeek = currentTime.getDay()
      const hour = currentTime.getHours()
      const munite = currentTime.getMinutes()
      // now 是白天还是晚上：
      const nowNight = (hour >= 20 || hour + munite*0.01 < 2.30)

      const isWeekday = dayOfWeek >= 1 && dayOfWeek <= 5

      const timePeriods = {
        day: { start: 9, end: 15, endmunite: 30, baseGold: '黄金9999' },
        night: { start: 20, end: 2, endmunite: 30, baseGold: '黄金(T+D)' }
      }

      let baseGold = timePeriods.day.baseGold
      const baseChange = 0.6
      // let buyChange = baseChange
      let buyChange = 0.8 + 0.2 + 0.2 + 0.2
      let sellChange = baseChange + 0.4
      // 通过后端接口获取金价最新调整：
      buyChange = buyChange + this.buyChange
      sellChange = sellChange + this.sellChange
       // 白天数据对比：
      const gold9999:GoldInfo = res.items.get('AU9999') as GoldInfo
      const goldTD:GoldInfo = res.items.get('AUTD') as GoldInfo
      // console.log('黄金9999', gold9999)
      // console.log('黄金(T+D)', goldTD)
      if (isWeekday) {
        this.isOpen = '开盘'
        if (hour >= timePeriods.night.start || hour < timePeriods.day.start) {
          baseGold = timePeriods.night.baseGold
        }
        if (
          (hour >= timePeriods.day.end &&
            munite > timePeriods.day.endmunite &&
            hour < timePeriods.night.start) ||
          (hour >= timePeriods.night.end && hour < timePeriods.day.start)) {
          this.isOpen = '闭盘'
        }
        // 这里谁的价格高，就用谁
        // td比9999的值低小于2毛，就+6毛，其他还是+5毛；然后哪个价格高就在哪个上面加。
        if (gold9999.Sell > goldTD.Sell) {
          baseGold = timePeriods.day.baseGold
          // if (gold9999.Sell - goldTD.Sell > 0.2) {
          //   baseChange = 0.6
          // }
        } else if (gold9999.Sell < goldTD.Sell) {
          baseGold = timePeriods.night.baseGold
        }
      } else {
        // 周末为晚上的数据
        baseGold = timePeriods.night.baseGold
        this.isOpen = '闭盘'
      }
      if (this.isOpenByBack !== '') {
        this.isOpen = this.isOpenByBack
      }
      // 因为销售和购买可能不一样：
      if (nowNight) { // 晚上对比td黄金
        baseGold = goldTD.name as string
      }
      const baseBuyGold:string = gold9999.name as string
      // 盘庚金
      // console.log('baseGold:', baseGold)
      const data = new Map<string, GoldInfo>()
      // 盘庚金数据添加
      for (const [, value] of res.items) {
        // 基础数据：
        if (value.name !== baseGold) {
          continue
        }
        const pggold: GoldInfo = {
          name: '黄金',
          Buy: parseFloat(value.Buy+"") - buyChange,
          Sell: parseFloat(value.Sell+'') + sellChange,
          H: parseFloat(value.H+'') + sellChange,
          L: parseFloat(value.L+'') + sellChange,
          MaxMni: {
            H: parseFloat(value.H+'') + sellChange,
            L: parseFloat(value.L+'') + sellChange
          },
          C: 'pggold'
        }
        data.set('黄金', pggold)
      }
      const pg: any = data.get('黄金')
      for (const [, value] of res.items) {
        if (value.name === baseBuyGold && !nowNight) { // 2024 0328 改动：回购价只在9999基础上-6毛。但是销售还是谁高用谁。
          pg.Buy = parseFloat(value.Buy+'') - buyChange
          break
        }
      }
      // console.log('我拿到的请求gold数据：', res.items)
      // const TableData: GoldInfo[] = []
      this.goldInfoList.push(pg)
      for (const name of sortName) {
        // for (const value of Object.values(res.items)) {
        for (const [key, value] of res.items) {
          // value.MaxMni = value.H + '/' + value.L
          if (value.name === '黄金') {
            continue
          }
          if (value.name !== name) {
            continue
          }
          value.Buy = parseFloat(value.Buy+'')
          value.Sell = parseFloat(value.Sell+'')
          value.H = parseFloat(value.H+'')
          value.L = parseFloat(value.L+'')
          value.MaxMni = {
            H: value.H,
            L: value.L
          }
          this.goldInfoList.push(value)
        }
      }
      // console.log('最后得到的gold数据：', TableData)
      // this.goldInfoList = TableData
      this.pubtime = res.pubtime
      this.buy = pg.Buy
      this.sell = pg.Sell
    },
    // 获取金价调整。
    async getBackGoldChange() :Promise<GoldInfo> {
      const ret :GoldInfo = {} as GoldInfo
      await ListGoldSetting({ priceType: 0 }).then((res) => {
        const lst = res.data
        for (const val of lst) {
          if (val.currencyCode == 'pggold') {
            ret.Buy = val.recyclePrice / 100
            ret.Sell = val.sellPrice / 100
            break
          }
        }
      }).catch((err) => {
        console.error('getBackGoldChange 请求接口失败:', err);
      })
      
      return ret
    },
    // 获取开闭盘控制。
    async getOpenClose() {
      GetOpenClose().then((res)=>{
        const now = new Date().getTime();
        let endTime: number;
        if (res.data.updateTime !== "") {
          endTime = new Date(res.data.updateTime as string).getTime() + res.data.effectHour! * 3600 * 1000
        }else {
          endTime = new Date().getTime() + res.data.effectHour! * 3600 * 1000
        }
        if (endTime - now <= 0) {
          this.isOpenByBack = ''
          return; // 不做处理
        }else {
          this.isOpenByBack = res.data.status == 1 ? '开盘' : '闭盘'
        }
        return
      }).catch(()=>{
        console.error('获取开闭盘数据失败')
      })
    }
  }
})
